import './markdownItMermaid.css'
import mermaid from 'mermaid'
import { BaseRenderer } from './BaseRenderer'

/**
 * Mermaid渲染器类（继承 BaseRenderer）
 */
class MermaidRenderer extends BaseRenderer {
  constructor() {
    super()
    this.mermaidInstance = mermaid
  }

  /**
   * 渲染Mermaid图表
   */
  renderMermaidCharts() {
    const mermaidElements = document.querySelectorAll('.mermaid:not([data-processed])')
    
    if (mermaidElements.length > 0 && this.mermaidInstance) {
      try {
        // 为每个Mermaid元素单独渲染
        mermaidElements.forEach((element, index) => {
          const code = element.textContent.trim()
          if (code) {
            // 保存原始代码（首次渲染时）
            if (!element.dataset.originalCode) {
              element.dataset.originalCode = code
            }
            
            // 生成唯一ID，避免冲突
            const uniqueId = 'mermaid-' + Date.now() + '-' + index + '-' + Math.random().toString(36).substr(2, 9)
            
            // 使用Mermaid的render方法渲染图表
            this.mermaidInstance.render(uniqueId, code).then(({ svg }) => {
              // 添加缩放控制按钮
              const controlsHtml = `
                <div class="mermaid-controls">
                  <button onclick="this.parentElement.parentElement.zoomIn()">+</button>
                  <button onclick="this.parentElement.parentElement.zoomOut()">-</button>
                  <button onclick="this.parentElement.parentElement.resetZoom()">重置</button>
                </div>
              `
              
              element.innerHTML = controlsHtml + svg
              element.setAttribute('data-processed', 'true')
              
              // 添加缩放和拖拽功能
              this.addZoomAndDragFunctionality(element)
            }).catch(error => {
              console.warn('Mermaid渲染失败:', error)
              element.innerHTML = `<pre class="error">Mermaid渲染失败: ${error.message || String(error)}</pre>`
              
              // 收集错误
              this.addError({
                type: 'Mermaid',
                message: error.message || String(error),
                code: code
              })
            })
          }
        })
      } catch (error) {
        console.warn('Mermaid渲染错误:', error)
      }
    }
  }

  /**
   * 添加缩放和拖拽功能
   */
  addZoomAndDragFunctionality(element) {
    const svg = element.querySelector('svg')
    if (!svg) return
    
    let scale = 1
    let translateX = 0
    let translateY = 0
    let isDragging = false
    let startX = 0
    let startY = 0
    
    // 缩放功能
    element.zoomIn = () => {
      scale = Math.min(scale * 1.2, 5)
      updateTransform()
    }
    
    element.zoomOut = () => {
      scale = Math.max(scale / 1.2, 0.2)
      updateTransform()
    }
    
    element.resetZoom = () => {
      scale = 1
      translateX = 0
      translateY = 0
      updateTransform()
    }
    
    function updateTransform() {
      svg.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scale})`
    }
    
    // 拖拽功能
    element.addEventListener('mousedown', (e) => {
      if (e.target.tagName === 'BUTTON') return
      isDragging = true
      startX = e.clientX - translateX
      startY = e.clientY - translateY
      element.style.cursor = 'grabbing'
    })
    
    element.addEventListener('mousemove', (e) => {
      if (!isDragging) return
      translateX = e.clientX - startX
      translateY = e.clientY - startY
      updateTransform()
    })
    
    element.addEventListener('mouseup', () => {
      isDragging = false
      element.style.cursor = 'grab'
    })
    
    element.addEventListener('mouseleave', () => {
      isDragging = false
      element.style.cursor = 'grab'
    })
    
    // 触摸设备支持
    element.addEventListener('touchstart', (e) => {
      if (e.target.tagName === 'BUTTON') return
      isDragging = true
      const touch = e.touches[0]
      startX = touch.clientX - translateX
      startY = touch.clientY - translateY
    })
    
    element.addEventListener('touchmove', (e) => {
      if (!isDragging) return
      const touch = e.touches[0]
      translateX = touch.clientX - startX
      translateY = touch.clientY - startY
      updateTransform()
      e.preventDefault()
    })
    
    element.addEventListener('touchend', () => {
      isDragging = false
    })
  }

  /**
   * 观察DOM变化（使用基类方法）
   */
  observeDOM(previewContainerSelector) {
    super.observeDOM(
      previewContainerSelector,
      'mermaid',
      () => this.renderMermaidCharts(),
      100
    )
  }
  
  // cleanup 使用基类默认实现
}

/**
 * markdown-it mermaid插件主函数
 */
export default function markdownItMermaid(md) {
  // 保存默认的fence渲染器
  const defaultFenceRender = md.renderer.rules.fence || 
    function(tokens, idx, options, env, self) {
      return self.renderToken(tokens, idx, options);
    };

  // 重写fence渲染规则
  md.renderer.rules.fence = (tokens, idx, options, env, self) => {
    const token = tokens[idx];
    const code = token.content.trim();
    const info = token.info.trim();

    // 处理mermaid代码块
    if (info === 'mermaid') {
      // 创建mermaid容器HTML
      return `
        <div class="mermaid">
          ${code}
        </div>
      `;
    }

    // 对于其他类型的代码块，使用默认渲染器
    return defaultFenceRender(tokens, idx, options, env, self);
  };
}

// 导出渲染器类供外部使用
export { MermaidRenderer }